package cn.cloud9.mybatisplusgenerator.controller;


import cn.cloud9.mybatisplusgenerator.config.MinioClientProperties;
import com.alibaba.fastjson.JSON;
import io.minio.*;
import io.minio.messages.Item;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@RestController
@RequestMapping("/minio")
public class MinioController {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    MinioClientProperties mcp;

    /**
     * /minio/list
     * @return
     * @throws Exception
     */
    @GetMapping("/list")
    public List<String> listBucketObject() throws Exception {
        final Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs
                        .builder()
                        .bucket(mcp.getBucketName())
                        .build()
        );

        final Iterator<Result<Item>> iterator = results.iterator();

        final ArrayList<String> objects = new ArrayList<>();

        while (iterator.hasNext()) {
            Item item = iterator.next().get();
            objects.add(item.objectName() + " " + item.size());
        }
        return objects;
    }

    /**
     * /minio/upload
     * @param files
     * @return
     */
    @PostMapping("/upload")
    public String upload(@RequestParam(name = "file", required = false)MultipartFile[] files) {
        if (null == files || files.length == 0) return "没有上传的文件！";

        final ArrayList<String> objects = new ArrayList<>(files.length);

        for (MultipartFile mFile : files) {

            // 先保存名称
            final String filename = mFile.getOriginalFilename();
            objects.add(filename);

            // 然后上传
            try {
                InputStream inputStream = mFile.getInputStream();

                // 上传可以获取一个输入流
                final ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs
                        .builder()
                        .bucket(mcp.getBucketName())
                        .object(filename)
                        .stream(inputStream, mFile.getSize(), -1)
                        .build()
                );

                final String etag = objectWriteResponse.etag();
                System.out.println(etag);

                inputStream.close();

            } catch (Exception exception) {
                exception.printStackTrace();
                return "上传失败！";
            }

        }
        return "上传成功 " + objects;

    }

    /**
     * /list/download/{fileName}
     * @param resp
     * @param fileName
     * @throws Exception
     */
    @GetMapping("/download/{fileName}")
    public void download(HttpServletResponse resp, @PathVariable("fileName") String fileName) throws Exception {

        InputStream inputStream = null;

        try {

            // 取出对象信息
            final StatObjectResponse statObject = minioClient.statObject(
                    StatObjectArgs
                            .builder()
                            .bucket(mcp.getBucketName())
                            .object(fileName)
                            .build()
            );

            // 设置下载类型的响应信息
            resp.setContentType(statObject.contentType());
            resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

            // 下载逻辑

            // 从客户端获取输入流（获取对象响应）
            final GetObjectResponse object = minioClient.getObject(
                    GetObjectArgs
                            .builder()
                            .bucket(mcp.getBucketName())
                            .object(fileName)
                            .build()
            );
            inputStream = object;
            // 输出文件
            IOUtils.copy(inputStream, resp.getOutputStream());


        } catch (Exception exception) {
            exception.printStackTrace();
        } finally {
            assert inputStream != null;
            inputStream.close();
        }
    }

    @DeleteMapping("/delete/{fileName}")
    public String delete(@PathVariable("fileName") String filename) {
        try {
            minioClient.removeObject(
                    RemoveObjectArgs
                            .builder()
                            .bucket(mcp.getBucketName())
                            .object(filename)
                            .build()
            );
        } catch (Exception exception) {
            exception.printStackTrace();
            return "删除失败！";
        }
        return "删除成功";
    }

}